package br.ufrn.dimap.ase.squid.metrics.visitors;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.emf.common.util.EList;

import br.ufrn.dimap.ase.squid.core.models.squidmodel.Feature;
import br.ufrn.dimap.ase.squid.core.models.squidmodel.Mapping;
import br.ufrn.dimap.ase.squid.core.models.squidmodel.impl.ClassImpl;
import br.ufrn.dimap.ase.squid.core.models.squidmodel.impl.CodePieceImpl;
import br.ufrn.dimap.ase.squid.core.models.squidmodel.impl.FieldImpl;
import br.ufrn.dimap.ase.squid.core.models.squidmodel.impl.MethodImpl;
import br.ufrn.dimap.ase.squid.metrics.views.tree.model.InfoNode;
import br.ufrn.dimap.ase.squid.metrics.views.tree.model.Resultado;


public class VisitorMetricTransversalidade extends AbstractVisitor {
	private static int NUMERO_METRICAS = 2;
	
	private int metricScatteringDegree = 0;
	private int metricTanglingDegree = 0;
	
	private List<InfoNode> lScatteringDegree;
	private List<InfoNode> lTanglingDegree;
	
	public VisitorMetricTransversalidade() {
		lScatteringDegree = new ArrayList<InfoNode>();
		lTanglingDegree = new ArrayList<InfoNode>();
	}
	
	/**
	 * Falta pegar o metodo e verificar se tem entrelacamento
	 */
	public void visit(ClassImpl classImpl){
		this.metricScatteringDegree++;
		lScatteringDegree.add(new InfoNode( getPath(classImpl) ));
	}

	public void visit(MethodImpl methodImpl){
		this.metricScatteringDegree++;
		lScatteringDegree.add(new InfoNode( getPath(methodImpl) ));
	}

	public void visit(FieldImpl nome){
		this.metricScatteringDegree++;
		lScatteringDegree.add(new InfoNode( getPath(nome) ));
	}
	
	public void visit(CodePieceImpl codePiece){
		this.metricScatteringDegree++;
		lScatteringDegree.add(new InfoNode( getPath(codePiece) ));
	}
	
	public Resultado[] getRestulados() {
		tirarRepeticoesListas(lScatteringDegree, lTanglingDegree);
		
		Resultado[] resultados = new Resultado[NUMERO_METRICAS];
		int n = 0;

		resultados[n++] = new Resultado(
				"Metric Scattering Degree: " + metricScatteringDegree,
				this.lScatteringDegree
			);
		resultados[n++] = new Resultado(
				"Metric Tangling Degree: " + metricTanglingDegree,
				this.lTanglingDegree
			);
		
		return resultados;
	}
	
	public void addTanglingDegree(Mapping mapping) {
		EList<Feature> features = mapping.getFeatures();
		String info = "";
		for(int i = 0; i < features.size(); i++) {
			if(i > 0) info += " - ";
			
			info += features.get(i).getName();
		}
		
		info += String.format(
				" (%s)", 
				mapping.getName().substring(0, mapping.getName().indexOf(".java"))
			);
		
		this.lTanglingDegree.add( new InfoNode(info) );
		this.metricTanglingDegree++;
	}

}
